#!/usr/bin/python
# vim:fileencoding=utf8

from gnTai.usefull_staff import textprocess
from gnTai.aiexception import AIException
from gnTai.words.article import Article
from gnTai.words.noun import Noun
from gnTai.concepts.object import Object
from gnTai.concepts.action import Action
from gnTai.thoughts.thought import Thought
from gnTai.knowledge.language import test_knowledge


class EnglishText2Thought:
    
    def __init__(self, knowledge):
        self.knowledge = knowledge
        
        
    def sentence2thought(self, sentence):
        sentence = sentence.strip()
        if sentence.endswith('?'):
            pass
        else:
            return self.statement2thought(sentence)
        
        
    def statement2thought(self, statement):
        """
        Переводит утверждение в мысль.
        Получает на вход строку с удаленными
        начальными и конечными пробельными символами.
        Возвращает мысль (класс Thought).
        """
        # Утверждение имеет структуру:
        # подлежащее сказуемое.
        # задача функции распознать эти части
        # и перевести слова в концепты (Concept)
        # План действий такой:
        #   1) Разбить предложение на список слов.
        #   2) Извлечь из начала подлежащее.
        #   3) Из начала того, что осталось, извлечь сказуемое.
        res = Thought()
        words = textprocess.text2words(statement)
        subject = self.extract_subject(words)
        action = self.extract_action(words)
        res.set_subject(subject)
        res.set_action(action)
        
        return res
    

    def extract_subject(self, words):
        """
        Извлекает подлежащее.
        """
        res = self.extract_object(words)
        if res is not None:
            return res
        else:
            raise AIException(u'Нелепая конструкция: нет подлежащего.')
            
        
    def extract_object(self, words):
        """
        Извлекает отрезок предложения, соответствующий объекту.
        Понимает не более одного артикля + существительное.
        """
        form = {}
        while True:
            if len(words) == 0:
                return None 
            elif self.knowledge.is_part_of_speech(words[0], 'article'):
                form = Article.base_form(words[0])[0][1]
                words.pop(0)
            elif self.knowledge.is_part_of_speech(words[0], 'noun'):
                base_form = Noun.base_form(words[0])[0]
                form.update(base_form[1])
                noun = self.knowledge.get_part_of_speech(base_form[0], 'noun')
                res = Object(noun, **form)
                words.pop(0)
                return res
            else:
                return None
    
    
    def extract_action(self, words):
        """
        Извлекает сказуемое из списка слов (предполагается, что подлежащее уже извлечено).
        """
        variants = self.knowledge.get_part_of_speech_(words.pop(0))
        if 'verb' in variants:
            verb = variants['verb'][0][0]
            if verb is self.knowledge.to_do:
                if len(words) > 0 and words[0] == 'not':
                    words.pop(0)
                    res = self.extract_action(words)
                    res.set_negative(True)
                    return res
            res = Action(verb, **(variants['verb'][0][1]))
            res.set_direct_object(self.extract_object(words))
            return res
        else:
            raise AIException(u'not an action')
    
    
if __name__ == "__main__":
    test = EnglishText2Thought(test_knowledge)
    print test.statement2thought("The apple does not do.")
    print test.statement2thought("The apple does not do.").set_question(True)
    
    print test.statement2thought("The apple is a fruit.")
    print test.statement2thought("The apple is a fruit.").set_question(True)
    
    print test.statement2thought("The man is worker.")
    print test.statement2thought("The man is worker.").set_question(True)
